package com.asen.test.view.BesselCurve

import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import android.view.animation.LinearInterpolator


/**
 * @date   : 2021/9/1
 * @author : asenLiang
 * @e-mail : liangAisiSen@163.com
 * @desc   : 贝塞尔曲线：水浪波
 */

class WaveView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private val mPaint: Paint = Paint()
    private val mPath: Path = Path()

    //一个波浪长，相当于两个二阶贝塞尔曲线的长度
    private val mItemWaveLength = 800f

    //波浪在Y轴方向的位置
    var originY = 800f // 向下偏移（根据安卓屏幕y坐标方向来看）

    //波浪幅度
    private val range = 100f
    private var dx = 0

    init {

        mPaint.color = Color.GREEN

        mPaint.style = Paint.Style.FILL_AND_STROKE

    }

    @SuppressLint("DrawAllocation")
    override fun onDraw(canvas: Canvas) {

        super.onDraw(canvas)

        mPath.reset()

        val halfWaveLen = mItemWaveLength / 2 //半个波长，即一个贝塞尔曲线长度

        mPath.moveTo(-mItemWaveLength + dx, originY) //波浪的开始位置

        //每一次for循环添加一个波浪的长度到path中，根据view的宽度来计算一共可以添加多少个波浪长度
        var i = -mItemWaveLength

        while (i <= width + mItemWaveLength) {

            mPath.rQuadTo(halfWaveLen / 2, -range, halfWaveLen, 0f)

            mPath.rQuadTo(halfWaveLen / 2, range, halfWaveLen, 0f)

            i += mItemWaveLength

        }

        mPath.lineTo(width.toFloat(), height.toFloat())

        mPath.lineTo(0f, height.toFloat())

        mPath.close() //封闭path路径
        val linearGradient = LinearGradient(
            0f,
            top.toFloat(),
            0f,
            bottom.toFloat(),
            intArrayOf(Color.CYAN,Color.BLUE),
            floatArrayOf(0f, 0.9f),
            Shader.TileMode.CLAMP
        )
        val shader = mPaint.shader

        mPaint.shader = linearGradient
        canvas.drawPath(mPath, mPaint)
        mPaint.shader = shader
    }

    /** 开始动画 */
    fun startAnim() {

        //根据一个动画不断得到0~mItemWaveLength的值dx，通过dx的增加不断去改变波浪开始的位置，dx的变化范围刚好是一个波浪的长度，
        //所以可以形成一个完整的波浪动画，假如dx最大小于mItemWaveLength的话， 就会不会画出一个完整的波浪形状
        val animator = ValueAnimator.ofInt(0, mItemWaveLength.toInt())

        animator.duration = 2000

        animator.repeatCount = ValueAnimator.INFINITE

        animator.interpolator = LinearInterpolator()

        animator.addUpdateListener { animation ->

            dx = animation.animatedValue as Int

            postInvalidate()

        }

        animator.start()

    }

}